package com.yupi.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.mapper.DepartmentMapper;
import com.yupi.springbootinit.model.dto.department.DepartmentQueryRequest;
import com.yupi.springbootinit.model.entity.Department;
import com.yupi.springbootinit.model.entity.User;
import com.yupi.springbootinit.model.vo.DepartmentVO;
import com.yupi.springbootinit.model.vo.UserVO;
import com.yupi.springbootinit.service.DepartmentService;
import com.yupi.springbootinit.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 部门服务实现
 */
@Service
@Slf4j
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department>
        implements DepartmentService {

    @Resource
    private UserService userService;

    @Override
    public void validDepartment(Department department, boolean add) {
        if (department == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String departmentName = department.getDepartmentName();
        String departmentCode = department.getDepartmentCode();

        // 创建时，参数不能为空
        if (add) {
            if (StringUtils.isAnyBlank(departmentName, departmentCode)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "部门名称和部门编号不能为空");
            }
            // 设置默认值：未删除状态
            if (department.getIsDelete() == null) {
                department.setIsDelete(0);
            }
        }
        // 有参数则校验
        if (StringUtils.isNotBlank(departmentName) && departmentName.length() > 256) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "部门名称过长");
        }
        if (StringUtils.isNotBlank(departmentCode) && departmentCode.length() > 128) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "部门编号过长");
        }

        // 校验部门编号唯一性（只检查未删除的部门）
        if (StringUtils.isNotBlank(departmentCode)) {
            QueryWrapper<Department> codeQueryWrapper = new QueryWrapper<>();
            codeQueryWrapper.eq("departmentCode", departmentCode);
            codeQueryWrapper.eq("isDelete", 0); // 只检查未删除的部门
            if (!add && department.getId() != null) {
                codeQueryWrapper.ne("id", department.getId());
            }
            long codeCount = this.count(codeQueryWrapper);
            if (codeCount > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "部门编号已存在");
            }
        }

        // 校验部门名称唯一性（只检查未删除的部门）
        if (StringUtils.isNotBlank(departmentName)) {
            QueryWrapper<Department> nameQueryWrapper = new QueryWrapper<>();
            nameQueryWrapper.eq("departmentName", departmentName);
            nameQueryWrapper.eq("isDelete", 0); // 只检查未删除的部门
            if (!add && department.getId() != null) {
                nameQueryWrapper.ne("id", department.getId());
            }
            long nameCount = this.count(nameQueryWrapper);
            if (nameCount > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "部门名称已存在");
            }
        }
    }

    @Override
    public QueryWrapper<Department> getQueryWrapper(DepartmentQueryRequest departmentQueryRequest) {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        if (departmentQueryRequest == null) {
            return queryWrapper;
        }
        Long id = departmentQueryRequest.getId();
        String departmentName = departmentQueryRequest.getDepartmentName();
        String departmentCode = departmentQueryRequest.getDepartmentCode();

        // 拼接查询条件
        queryWrapper.eq(id != null, "id", id);
        queryWrapper.like(StringUtils.isNotBlank(departmentName), "departmentName", departmentName);
        queryWrapper.like(StringUtils.isNotBlank(departmentCode), "departmentCode", departmentCode);
        queryWrapper.orderByDesc("createTime");
        return queryWrapper;
    }

    @Override
    public DepartmentVO getDepartmentVO(Department department) {
        if (department == null) {
            return null;
        }
        DepartmentVO departmentVO = new DepartmentVO();
        BeanUtils.copyProperties(department, departmentVO);
        return departmentVO;
    }

    @Override
    public List<DepartmentVO> getDepartmentVO(List<Department> departmentList) {
        if (departmentList == null) {
            return null;
        }
        return departmentList.stream().map(this::getDepartmentVO).collect(Collectors.toList());
    }

    @Override
    public List<DepartmentVO> getAllDepartments() {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("departmentCode");
        List<Department> departmentList = this.list(queryWrapper);
        return getDepartmentVO(departmentList);
    }

    @Override
    public List<UserVO> getUsersByDepartmentId(Long departmentId) {
        if (departmentId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "部门ID不能为空");
        }
        
        // 先检查部门是否存在
        Department department = this.getById(departmentId);
        if (department == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "部门不存在");
        }
        
        // 查询该部门下的所有用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("departmentId", departmentId);
        queryWrapper.orderByDesc("createTime");
        List<User> userList = userService.list(queryWrapper);
        
        return userService.getUserVO(userList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<UserVO> transferUsersToUnassigned(Long departmentId) {
        if (departmentId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "部门ID不能为空");
        }
        
        // 获取或创建"未分配"部门
        Department unassignedDepartment = getOrCreateUnassignedDepartment();
        
        // 如果要删除的就是"未分配"部门，不允许删除
        if (departmentId.equals(unassignedDepartment.getId())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "不能删除未分配部门");
        }
        
        // 查询该部门下的所有用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("departmentId", departmentId);
        List<User> userList = userService.list(queryWrapper);
        
        if (userList.isEmpty()) {
            return new ArrayList<>(); // 没有用户需要更新，返回空列表
        }
        
        // 使用SQL更新方式，将该部门下所有用户转移到"未分配"部门
        User updateUser = new User();
        updateUser.setDepartmentId(unassignedDepartment.getId());
        
        QueryWrapper<User> updateWrapper = new QueryWrapper<>();
        updateWrapper.eq("departmentId", departmentId);
        
        boolean result = userService.update(updateUser, updateWrapper);
        
        if (!result) {
            log.error("转移部门ID为 {} 的用户到未分配部门失败", departmentId);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "转移用户到未分配部门失败");
        }
        
        // 添加日志记录
        log.info("成功将部门ID为 {} 的 {} 名用户转移到未分配部门(ID: {})", 
                departmentId, userList.size(), unassignedDepartment.getId());
        
        // 返回受影响的用户列表（更新后的用户信息）
        for (User user : userList) {
            user.setDepartmentId(unassignedDepartment.getId());
        }
        return userService.getUserVO(userList);
    }

    @Override
    public Department getOrCreateUnassignedDepartment() {
        // 先查询是否已存在"未分配"部门
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("departmentCode", "UNASSIGNED");
        Department unassignedDepartment = this.getOne(queryWrapper);
        
        if (unassignedDepartment == null) {
            // 如果不存在，则创建"未分配"部门
            unassignedDepartment = new Department();
            unassignedDepartment.setDepartmentName("未分配部门");
            unassignedDepartment.setDepartmentCode("UNASSIGNED");
            unassignedDepartment.setIsDelete(0);
            
            boolean saved = this.save(unassignedDepartment);
            if (!saved) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "创建未分配部门失败");
            }
            
            log.info("创建未分配部门成功，部门ID: {}", unassignedDepartment.getId());
        }
        
        return unassignedDepartment;
    }
}
